#pragma once
#include "prs_Attr.h"

namespace prs {
///////////////////////////////////////////////////////////////////////////////
struct TDataFieldRefT;
struct TDataFieldRefR;
struct TDataFieldRefTR;
struct TDataFields;
struct TDataTableRecord;		
struct TDataTableRecords;
struct TDataRefRRecord;
//struct TDataValueRefT;
struct TDataValueString;
struct TDataValueInteger;
struct TDataValueDouble;
struct TDataValueDateTime;
struct TDataValueRefR;
struct TDataValueRefTR;
struct TDataTable;
///////////////////////////////////////////////////////////////////////////////

struct TDataDict : public TAttrNode
{
  static const char *nodeType_TDataFieldString;
  static const char *nodeType_TDataFieldInteger;
  static const char *nodeType_TDataFieldDouble;
  static const char *nodeType_TDataFieldDateTime;
  //static const char *nodeType_TDataFieldRefT;
  static const char *nodeType_TDataFieldRefR;
  static const char *nodeType_TDataFieldRefTR;
  static const char *nodeType_TDataValueString;
  static const char *nodeType_TDataValueInteger;
  static const char *nodeType_TDataValueDouble;
  static const char *nodeType_TDataValueDateTime;
  //static const char *nodeType_TDataValueRefT;
  static const char *nodeType_TDataValueRefR;
  static const char *nodeType_TDataValueRefTR;
  static const char *nodeType_TDataTableRecord;
  //static const char *nodeType_TDataRefTRecord;
  static const char *nodeType_TDataRefRRecord;
  static const char *nodeType_TDataRefTRRecord;
  static const char *nodeType_TDataTable;
  static const char *nodeType_TDataTables;

  static const char *attrName_Musor;
  static const char *attrName_Musor2;

  static const char *attrName_TableId;
  static const char *attrName_FieldId;
  static const char *attrName_RecordId;
  
  static const char *attrName_ToTableId;
  static const char *attrName_ToRecordId;

  static const char *attrName_Null;
  static const char *attrName_Value;
  static const char *attrName_Values;
  static const char *attrName_TablePtr;
  static const char *attrName_FieldPtr;
  static const char *attrName_Records;
  static const char *attrName_Fields;
  static const char *attrName_Size;
  static const char *attrName_Tables;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TTableId
{
	TTableId(const char* Id) : id(Id) {}
	TTableId(const svl::TString &Id) : id(Id) {}
	TTableId(TAttrStringBase &Attr) : id(Attr.GetValue()) {}
	//
	void SetId(char* Id) { id = Id;}
	svl::TString GetId() const { return id;}
	
private:
	svl::TString id;	
};

///////////////////////////////////////////////////////////////////////////////

struct TFieldId
{
	TFieldId(const char* Id) : id(Id) {}
	TFieldId(const svl::TString &Id) : id(Id) {}
	TFieldId(TAttrStringBase &Attr) : id(Attr.GetValue()) {}
	//
	void SetId(char* Id) { id = Id;}
	svl::TString GetId() const { return id;}
	
private:
	svl::TString id;	
};

///////////////////////////////////////////////////////////////////////////////

struct TRecordId
{
	TRecordId(int Id) : id(Id) {}
	TRecordId(TAttrIntegerBase &Attr) : id(Attr.GetValue()) {}
	//
	void SetId(int Id) { id = Id;}
	int  GetId() const { return id;}
	
private:
	int id;	
};

///////////////////////////////////////////////////////////////////////////////
// Fields /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataField : public TDataDict
{
  TAttrString<attrName_FieldId> FieldId;
  TAttrPointer<attrName_TablePtr,TDataTable*> TablePtr;
  //
  TDataField() : FieldId(this),TablePtr(this) {}
  //
  TDataTable *GetTable() { return TablePtr;}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record)=0;
  friend TDataFields;
  friend TDataTableRecords;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataFieldString : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldString> NodeType;
  TAttrInteger<attrName_Size> Size;
  //
  TDataFieldString() : NodeType(this),Size(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);
};

///////////////////////////////////////////////////////////////////////////////

struct TDataFieldInteger : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldInteger> NodeType;
  //
  TDataFieldInteger() : NodeType(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);
};

///////////////////////////////////////////////////////////////////////////////

struct TDataFieldDouble : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldDouble> NodeType;
  //
  TDataFieldDouble() : NodeType(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);
};

///////////////////////////////////////////////////////////////////////////////

struct TDataFieldDateTime : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldDateTime> NodeType;
  //
  TDataFieldDateTime() : NodeType(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataFields : public TNodeArrayT<TDataField>
{
  void AddFieldString  (const TFieldId &FieldId,int Size = 30);
  void AddFieldInteger (const TFieldId &FieldId);
  void AddFieldDouble  (const TFieldId &FieldId);
  void AddFieldDateTime(const TFieldId &FieldId);
  //
  TDataFieldRefR  *AddFieldRefR (const TFieldId &FieldId,const TTableId &ToTableId);
  TDataFieldRefTR *AddFieldRefTR(const TFieldId &FieldId);
  //
  TDataField *GetField(const TFieldId &FieldId);
  //
  TDataFieldRefR  *GetFieldRefR (const TFieldId &FieldId);
  TDataFieldRefTR *GetFieldRefTR(const TFieldId &FieldId);
  
private:
	void AddField(TDataField *Field);
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/***************
struct TDataFieldRefT : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldRefT> NodeType;
  //
  TDataFieldRefT() : NodeType(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);

private:
  svl_Except;
};
******************/
///////////////////////////////////////////////////////////////////////////////

struct TDataFieldRefR : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldRefR> NodeType;
  TAttrString<attrName_ToTableId> ToTableId;
  //
  TDataFieldRefR() : NodeType(this),ToTableId(this) {}
  //
  TDataTable *GetToTable();

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);

private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataFieldRefTR : public TDataField
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataFieldRefTR> NodeType;
  //
  TDataFieldRefTR() : NodeType(this) {}

protected:
  virtual void AddValueToTableRecord(TDataTableRecord &Record);

private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataValue : public TDataDict
{
	virtual TDataField *GetField() = 0;
  virtual void SetNull() = 0;
  virtual bool GetNull() = 0;
	virtual svl::TString GetValueAsString(){ return ""; };
};

///////////////////////////////////////////////////////////////////////////////

struct TDataValues : public TNodeArrayT<TDataValue>
{
	TDataTable *GetTable();
  TDataValue *GetValue(const TFieldId &FieldId);
  //
  int GetNValue(TDataValue *Value) { return GetN(Value);}
};

///////////////////////////////////////////////////////////////////////////////
// Records ////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataTableRecord : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataTableRecord> NodeType;
  TAttrInteger<attrName_RecordId> RecordId;
  TAttrNodeArray<attrName_Values,TDataValues> Values;
  //
  TDataTableRecord() : NodeType(this),RecordId(this),Values(this) {}
	//
	TDataTable *GetTable() { return Values.Array.GetTable();}
  //
  TDataValue *GetValueByFieldId(const TFieldId &FieldId) { return Values.Array.GetValue(FieldId);}
  TDataValue *GetValue         (const TFieldId &FieldId) { return Values.Array.GetValue(FieldId);}
  //
  void SetValueString  (const TFieldId &FieldId,svl::TString   Value);
  void SetValueInteger (const TFieldId &FieldId,int            Value);
  void SetValueDouble  (const TFieldId &FieldId,double         Value);
  void SetValueDateTime(const TFieldId &FieldId,svl::TDateTime Value);
  //
  TDataRefRRecord *AddValueRefR     (const TFieldId &FieldId,const TRecordId &ToRecordId) { return AddValueRefRLast(FieldId,ToRecordId);}
  TDataRefRRecord *AddValueRefRFirst(const TFieldId &FieldId,const TRecordId &ToRecordId);
  TDataRefRRecord *AddValueRefRLast (const TFieldId &FieldId,const TRecordId &ToRecordId);
  //
  TDataRefRRecord *AddValueRefRBefore(const TFieldId &FieldId,TDataRefRRecord *Current,const TRecordId &ToRecordId);
  TDataRefRRecord *AddValueRefRAfter (const TFieldId &FieldId,TDataRefRRecord *Current,const TRecordId &ToRecordId);
  //
  void AddValueRefTR(const TFieldId &FieldId,const TTableId &ToTableId,const TRecordId &ToRecordId);
  //
  TDataValueString   *GetValueString  (const TFieldId &FieldId);
  TDataValueInteger  *GetValueInteger (const TFieldId &FieldId);
  TDataValueDouble   *GetValueDouble  (const TFieldId &FieldId);
  TDataValueDateTime *GetValueDateTime(const TFieldId &FieldId);
  //
  TDataValueRefR  *GetValueRefR (const TFieldId &FieldId);
  TDataValueRefTR *GetValueRefTR(const TFieldId &FieldId);
  //
  TDataValueString *GetFirstValueString();
  //
  void SetValueForExplorer(const svl::TString &in_Value);
  void GetValueForExplorer(svl::TString &out_Value);
  
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataTableRecords : public TNodeArrayT<TDataTableRecord>
{												
	int Count()									 { return TNodeArrayT<TDataTableRecord>::Count();}
	TDataTableRecord &Get(int N) { return TNodeArrayT<TDataTableRecord>::Get(N);}
	//TDataTable *GetTable();
	TRecordId NewRecordId();
	//
  TDataTableRecord *AddRecord(const TRecordId &RecordId);
  TDataTableRecord *GetRecord(const TRecordId &RecordId);
  //
  TDataTableRecord *GetFirstRecord() { return GetFirst();}
};
/***************
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataRefTRecord : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataRefTRecord> NodeType;
  TAttrString<attrName_ToTableId> ToTableId;
  //
  TDataRefTRecord() : NodeType(this),ToTableId(this) {}
  //
  TDataTable *GetToTable();

private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataRefTRecords : public TNodeArrayT<TDataRefTRecord>
{
  TDataRefTRecord *AddRecord(char *ToTableId);
  TDataRefTRecord *GetRecord(char *ToTableId);
};
*************************/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataRefRRecord : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataRefRRecord> NodeType;
  TAttrInteger<attrName_ToRecordId> ToRecordId;
  //
  TDataRefRRecord() : NodeType(this),ToRecordId(this) {}
  //
  TDataTable       *GetToTable();
  TDataTableRecord *GetToRecord();
  
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataRefRRecords : public TNodeArrayT<TDataRefRRecord>
{
	TDataTableRecord *GetToRecord(int N);
	//void GetToRecords(TDataTableRecords &ToRecords);
	//
  TDataRefRRecord *AddRecordFirst(const TRecordId &ToRecordId);
  TDataRefRRecord *AddRecordLast (const TRecordId &ToRecordId);
	//
  TDataRefRRecord *AddRecordBefore(TDataRefRRecord *Current,const TRecordId &ToRecordId);
  TDataRefRRecord *AddRecordAfter (TDataRefRRecord *Current,const TRecordId &ToRecordId);
  //
  TDataRefRRecord *GetRecord(const TRecordId &ToRecordId);
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataRefTRRecord : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataRefTRRecord> NodeType;
  TAttrString<attrName_ToTableId> ToTableId;
  TAttrInteger<attrName_ToRecordId> ToRecordId;
  //
  TDataRefTRRecord() : NodeType(this),ToTableId(this),ToRecordId(this) {}
  //
  TDataTable       *GetToTable();
  TDataTableRecord *GetToRecord();

private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataRefTRRecords : public TNodeArrayT<TDataRefTRRecord>
{
	//void GetToRecords(TDataTableRecords &ToRecords);
	//
  TDataRefTRRecord *AddRecord(const TTableId &ToTableId,const TRecordId &ToRecordId);
  TDataRefTRRecord *GetRecord(const TTableId &ToTableId,const TRecordId &ToRecordId);
};

///////////////////////////////////////////////////////////////////////////////
// Values /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataValueString : public TDataValue
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueString> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldString*> FieldPtr;
  //
  TDataValueString() : NodeType(this),FieldPtr(this),Null(this),Value(this) { Null = true;}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  virtual void SetNull()				 { Null = true;}
	virtual bool GetNull()         { return Null;}
  //
  void SetValue(svl::TString V) { Value = V; Null = false;}
  svl::TString GetValue()       { if (GetNull()) { Except("GetValue[GetNull]");} return Value.GetValue();}
  virtual svl::TString GetValueAsString(){ if( GetNull() ) return ""; return Value.GetValue(); }
  
private:
  TAttrBool<attrName_Null> Null;
  TAttrString<attrName_Value> Value;
  friend TDataFieldString;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataValueInteger : public TDataValue
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueInteger> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldInteger*> FieldPtr;
  //
  TDataValueInteger() : NodeType(this),FieldPtr(this),Null(this),Value(this) { Value = 0; Null = true;}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  virtual void SetNull()				 { Null = true;}
	virtual bool GetNull()         { return Null;}
  //
  void SetValue(int V) { Value = V; Null = false;}
  int  GetValue()      { if (GetNull()) { Except("GetValue[GetNull]");} return Value.GetValue();}
  virtual svl::TString GetValueAsString(){ if( GetNull() ) return ""; return svl::TString() << Value.GetValue(); }

private:
  TAttrBool<attrName_Null> Null;
  TAttrInteger<attrName_Value> Value;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataValueDouble : public TDataValue
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueDouble> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldDouble*> FieldPtr;
  //
  TDataValueDouble() : NodeType(this),FieldPtr(this),Null(this),Value(this) { Value.SetValue(0); Null.SetValue(true);}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  virtual void SetNull()				 { Null = true;}
	virtual bool GetNull()         { return Null;}
  //
  void SetValue(double V) { Value.SetValue(V); Null.SetValue(false);}
  double GetValue()       { if (GetNull()) { Except("GetValue[GetNull]");} return Value.GetValue();}
  virtual svl::TString GetValueAsString(){ if( GetNull() ) return ""; return svl::TString() << Value.GetValue(); }

private:
  TAttrBool<attrName_Null> Null;
  TAttrDouble<attrName_Value> Value;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataValueDateTime : public TDataValue
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueDateTime> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldDateTime*> FieldPtr;
  //
  TDataValueDateTime() : NodeType(this),FieldPtr(this),Null(this),Value(this) { Null.SetValue(true);}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  virtual void SetNull()				 { Null = true;}
	virtual bool GetNull()         { return Null;}
  //
  void SetValue(svl::TDateTime V) { Value.SetValue(V); Null.SetValue(false);}
  svl::TDateTime GetValue()       { if (GetNull()) { Except("GetValue[GetNull]");} return Value.GetValue();}
  virtual svl::TString GetValueAsString(){ if( GetNull() ) return ""; return Value.GetValue().DateTimeString(); }

private:
  TAttrBool<attrName_Null> Null;
  TAttrDateTime<attrName_Value> Value;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*****************
struct TDataValueRefT : public TDataValue
{
public:
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueRefT> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldRefT*> FieldPtr;
  TAttrNodeArray<attrName_Value,TDataRefTRecords> Value;
  //
  TDataValueRefT() : NodeType(this),FieldPtr(this),Value(this) {}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  //
  TDataRefTRecord *AddRecord(char *TableId) { return Value.Array.AddRecord(TableId);}
  TDataRefTRecord *GetRecord(char *TableId) { return Value.Array.GetRecord(TableId);}
  
private:
  svl_Except;
};
*************************/
///////////////////////////////////////////////////////////////////////////////

struct TDataValueRefR : public TDataValue
{
public:
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueRefR> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldRefR*> FieldPtr;
  TAttrNodeArray<attrName_Value,TDataRefRRecords> Value;
  //
  TDataValueRefR() : NodeType(this),FieldPtr(this),Value(this) {}
  //
	virtual TDataField *GetField() { return FieldPtr;}
  virtual void SetNull()				 {}
	virtual bool GetNull()         { return false;}
  //
  TDataTable       *GetToTable() { return FieldPtr.GetValue()->GetToTable();}
  TDataRefRRecords *GetRecords() { return &Value.Array;}
  //
  TDataRefRRecord *AddRecordFirst(const TRecordId &ToRecordId) { return Value.Array.AddRecordFirst(ToRecordId);}
  TDataRefRRecord *AddRecordLast (const TRecordId &ToRecordId) { return Value.Array.AddRecordLast (ToRecordId);}
  //
  TDataRefRRecord *AddRecordBefore(TDataRefRRecord *Current,const TRecordId &ToRecordId) { return Value.Array.AddRecordBefore(Current,ToRecordId);}
  TDataRefRRecord *AddRecordAfter (TDataRefRRecord *Current,const TRecordId &ToRecordId) { return Value.Array.AddRecordAfter (Current,ToRecordId);}
  //
  TDataRefRRecord *GetRecord(const TRecordId &ToRecordId) { return Value.Array.GetRecord(ToRecordId);}
  //
  //void GetToRecords(TDataTableRecords &ToRecords) { Value.Array.GetToRecords(ToRecords);}
  //
  virtual svl::TString GetValueAsString(){
	  svl::TString str,s;
	  for(int k = 0; k < Value.Array.Count(); ++k){
			TDataTableRecord *rec = Value.Array.GetToRecord(k);
			if( rec ){
				if(k) str << ",";
				rec->GetValueForExplorer(s);
				str << s;
			}
		}
	  return str;
  }
  
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TDataValueRefTR : public TDataValue
{
public:
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataValueRefTR> NodeType;
  TAttrPointer<attrName_FieldPtr,TDataFieldRefTR*> FieldPtr;
  TAttrNodeArray<attrName_Value,TDataRefTRRecords> Value;
  //
  TDataValueRefTR() : NodeType(this),FieldPtr(this),Value(this) {}
  //
	virtual TDataField *GetField() { return FieldPtr; }
  virtual void SetNull()				 {}
	virtual bool GetNull()         { return false;}
  //
  TDataRefTRRecord *AddRecord(const TTableId &TableId,const TRecordId &RecordId) { return Value.Array.AddRecord(TableId,RecordId);}
  TDataRefTRRecord *GetRecord(const TTableId &TableId,const TRecordId &RecordId) { return Value.Array.GetRecord(TableId,RecordId);}
  //
  //void GetToRecords(TDataTableRecords &ToRecords) { Value.Array.GetToRecords(ToRecords);}
  //
  virtual svl::TString GetValueAsString(){
	  svl::TString str,s;
	  for(int k = 0; k < Value.Array.Count(); ++k){
	      str << "toTableId="   << Value.Array.Get(k).ToTableId.GetValue();
	      str << " toRecordId=" << Value.Array.Get(k).ToRecordId.GetValue();
		  str << "\r";
	  }
	  return str;
  }
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataTable : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataTable> NodeType;
  TAttrString<attrName_TableId> TableId;
  TAttrNodeArray<attrName_Fields,TDataFields> Fields;
  TAttrNodeArray<attrName_Records,TDataTableRecords> Records;
  //
  TDataTable() : NodeType(this),TableId(this),Fields(this),Records(this) {}

	// Info ///////////////////////////////
	
	
  // Fields //////////////////////////////////////////////////
  void AddFieldString  (const TFieldId &FieldId,int Size = 30) { Fields.Array.AddFieldString(FieldId,Size);}
  void AddFieldInteger (const TFieldId &FieldId)               { Fields.Array.AddFieldInteger(FieldId);}
  void AddFieldDouble  (const TFieldId &FieldId)               { Fields.Array.AddFieldDouble(FieldId);}
  void AddFieldDateTime(const TFieldId &FieldId)               { Fields.Array.AddFieldDateTime(FieldId);}
  //
  TDataFieldRefR  *AddFieldRefR (const TFieldId &FieldId,const TTableId &ToTableId) { return Fields.Array.AddFieldRefR (FieldId,ToTableId);}
  TDataFieldRefTR *AddFieldRefTR(const TFieldId &FieldId)                           { return Fields.Array.AddFieldRefTR(FieldId);}
  //
  TDataField *GetField(const TFieldId &FieldId) { return Fields.Array.GetField(FieldId);}
  //
  TDataFieldRefR  *GetFieldRefR (const TFieldId &FieldId) { return Fields.Array.GetFieldRefR (FieldId);}
  TDataFieldRefTR *GetFieldRefTR(const TFieldId &FieldId) { return Fields.Array.GetFieldRefTR(FieldId);}

  // Records /////////////////////////////////////////////////////////
	TRecordId NewRecordId()       { return Records.Array.NewRecordId();}
  TDataTableRecord *AddRecord() { return Records.Array.AddRecord(NewRecordId());}
	//
  TDataTableRecord *AddRecord(const TRecordId &RecordId) { return Records.Array.AddRecord(RecordId);}
  TDataTableRecord *GetRecord(const TRecordId &RecordId) { return Records.Array.GetRecord(RecordId);}
};

///////////////////////////////////////////////////////////////////////////////

struct TDataTables : public TDataDict
{
  DECLARE_ClientNode()
  //
  TAttrNodeType<nodeType_TDataTables> NodeType;
  TAttrNodeArray<attrName_Tables,TNodeArray> Tables;
  //
  TDataTables() : NodeType(this),Tables(this) {}
  //
  TDataTable *AddTable(const TTableId &TableId);
  TDataTable *GetTable(const TTableId &TableId);
  //
  static TDataTable *GetTableFromChild(const TTableId &TableId,TNode *FromChild);
  
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TDataTypedRecordBase : public TDebug
{
	virtual TTableId  GetTableId()  const = 0;
	virtual TRecordId GetRecordId() const = 0;
};

///////////////////////////////////////////////////////////////////////////////
}
